#include "test_LocalOrderSubjectThread.h"
#include <QTest>
#include <QSignalSpy>
#include "3rdParty/trojita/Imap/Parser/ThreadingNode.h"
#include "../mock/MockMailboxListModel.h"

namespace Imap {
namespace Mailbox {

QList<UidSubject> list = {
    {1, "subject", QDateTime()}
};

QVector<Imap::Responses::ThreadingNode> listResult = {
    {1}
};

//sort by date, different subject
QList<UidSubject> list2 = {
    {1, "subject", QDateTime::currentDateTime()},
    {3, "subject2", QDateTime::currentDateTime().addDays(1)}
};

QVector<Imap::Responses::ThreadingNode> listResult2 = {
    {1}, {3}
};

//sort by date, same subject
QList<UidSubject> list3 = {
    {1, "subject", QDateTime::currentDateTime()},
    {3, "subject", QDateTime::currentDateTime().addDays(1)}
};

QVector<Imap::Responses::ThreadingNode> listResult3 = {
    {3, {1}}
};

void TestLocalOrderedSubjectThreadTask::testThreadForNumberOfMailsImp()
{
    m_task = new LocalOrderedSubjectThreadTask(0, QModelIndex());
    QVERIFY(listResult == m_task->runOrderedSubjectImp(list));
    QVERIFY(listResult2 == m_task->runOrderedSubjectImp(list2));
    QVERIFY(listResult3 == m_task->runOrderedSubjectImp(list3));
}

#define WORKFLOW_SINCE QDateTime::currentDateTime().addDays(-10)
QList<MockMessage> testWorkflowData1 = {
    {2, "subject", QDateTime::currentDateTime().addDays(-1), true}
};
QVector<Imap::Responses::ThreadingNode> testWorkflowResult1 = {
    {2}
};

QList<MockMessage> testWorkflowData2 = {
    {2, "subject", QDateTime::currentDateTime().addDays(-2), false}
};
QVector<Imap::Responses::ThreadingNode> testWorkflowResult2 = {
    {2}
};

QList<MockMessage> testWorkflowData3 = {
    {1, "subject2", QDateTime::currentDateTime().addDays(-9), false},
    {2, "subject1", QDateTime::currentDateTime().addDays(-2), false},
    {3, "Re: subject1", QDateTime::currentDateTime().addDays(-1), true}
};
QVector<Imap::Responses::ThreadingNode> testWorkflowResult3 = {
    {1}, {3, {2}}
};

QList<MockMessage> testWorkflowData4 = {
    {1, "subject2", QDateTime::currentDateTime().addDays(-15), false},
    {2, "Re: subject2", QDateTime::currentDateTime().addDays(-9), false},
    {3, "subject1", QDateTime::currentDateTime().addDays(-2), false},
    {4, "Re: subject1", QDateTime::currentDateTime().addDays(-1), true}
};
QVector<Imap::Responses::ThreadingNode> testWorkflowResult4 = {
    {2, {1}}, {4, {3}}
};

void TestLocalOrderedSubjectThreadTask::testWorkflow()
{
    runWorkflowTest(testWorkflowData1, testWorkflowResult1, WORKFLOW_SINCE);
    runWorkflowTest(testWorkflowData2, testWorkflowResult2, WORKFLOW_SINCE);
    runWorkflowTest(testWorkflowData3, testWorkflowResult3, WORKFLOW_SINCE);
    runWorkflowTest(testWorkflowData4, testWorkflowResult4, WORKFLOW_SINCE);
}

void TestLocalOrderedSubjectThreadTask::handleThreadingAvailable(QModelIndex mailboxIndex, QByteArray algorithm, QStringList search, QVector<Responses::ThreadingNode> map)
{
    m_map = map;
}

void TestLocalOrderedSubjectThreadTask::runWorkflowTest(QList<MockMessage> input, QVector<Responses::ThreadingNode> result, QDateTime since)
{
    MockMailboxListModel mailbox;
    mailbox.setMockData(input);
    m_task = new LocalOrderedSubjectThreadTask(0, mailbox.index(0, 0));
    connect(m_task, SIGNAL(threadingAvailable(QModelIndex,QByteArray,QStringList,QVector<Imap::Responses::ThreadingNode>)),
            this, SLOT(handleThreadingAvailable(QModelIndex,QByteArray,QStringList,QVector<Imap::Responses::ThreadingNode>)));
    connect(&mailbox, SIGNAL(dataChanged(QModelIndex,QModelIndex)), m_task, SLOT(handleDataChanged(QModelIndex,QModelIndex)));
    m_map.clear();
    QSignalSpy spy(m_task, SIGNAL(threadingAvailable(QModelIndex,QByteArray,QStringList,QVector<Imap::Responses::ThreadingNode>)));
    m_task->workflow();
    spy.wait(1000);
    QVERIFY(m_map == result);

}

}
}

QTEST_MAIN(Imap::Mailbox::TestLocalOrderedSubjectThreadTask)
